package com.seafood.controller;

import com.seafood.common.Result;
import com.seafood.service.WebSocketService;
import com.seafood.websocket.WebSocketStatistics;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * WebSocket管理控制器
 * 
 * @author System
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/api/websocket")
@RequiredArgsConstructor
@Tag(name = "WebSocket管理", description = "WebSocket消息推送和管理相关接口")
public class WebSocketController {

    private final WebSocketService webSocketService;

    @Operation(summary = "向指定用户发送消息")
    @PostMapping("/send-to-user")
    public Result<Void> sendMessageToUser(@RequestBody SendMessageRequest request) {
        log.info("发送消息到用户: userId={}, type={}", request.getUserId(), request.getType());
        
        try {
            webSocketService.sendMessageToUser(request.getUserId(), request.getType(), 
                    request.getContent(), request.getData());
            return Result.success("消息发送成功", null);
        } catch (Exception e) {
            log.error("发送消息到用户失败", e);
            return Result.error("发送消息失败：" + e.getMessage());
        }
    }

    @Operation(summary = "广播消息到指定主题")
    @PostMapping("/broadcast-to-topic")
    public Result<Void> broadcastToTopic(@RequestBody BroadcastRequest request) {
        log.info("广播消息到主题: topic={}, type={}", request.getTopic(), request.getType());
        
        try {
            webSocketService.broadcastToTopic(request.getTopic(), request.getType(), 
                    request.getContent(), request.getData());
            return Result.success("消息广播成功", null);
        } catch (Exception e) {
            log.error("广播消息到主题失败", e);
            return Result.error("消息广播失败：" + e.getMessage());
        }
    }

    @Operation(summary = "广播消息到所有客户端")
    @PostMapping("/broadcast-to-all")
    public Result<Void> broadcastToAll(@RequestBody BroadcastRequest request) {
        log.info("广播消息到所有客户端: type={}", request.getType());
        
        try {
            webSocketService.broadcastToAll(request.getType(), request.getContent(), request.getData());
            return Result.success("消息广播成功", null);
        } catch (Exception e) {
            log.error("广播消息到所有客户端失败", e);
            return Result.error("消息广播失败：" + e.getMessage());
        }
    }

    @Operation(summary = "发送订单状态更新通知")
    @PostMapping("/order-status-update")
    public Result<Void> sendOrderStatusUpdate(@RequestBody OrderStatusUpdateRequest request) {
        log.info("发送订单状态更新通知: userId={}, orderId={}", request.getUserId(), request.getOrderId());
        
        try {
            webSocketService.sendOrderStatusUpdate(request.getUserId(), request.getOrderId(), 
                    request.getStatus(), request.getMessage());
            return Result.success("订单状态更新通知发送成功", null);
        } catch (Exception e) {
            log.error("发送订单状态更新通知失败", e);
            return Result.error("发送通知失败：" + e.getMessage());
        }
    }

    @Operation(summary = "发送冷链异常报警通知")
    @PostMapping("/cold-chain-alert")
    public Result<Void> sendColdChainAlert(@RequestBody ColdChainAlertRequest request) {
        log.info("发送冷链异常报警通知: userId={}, alertType={}", request.getUserId(), request.getAlertType());
        
        try {
            webSocketService.sendColdChainAlert(request.getUserId(), request.getAlertType(), 
                    request.getMessage(), request.getAlertData());
            return Result.success("冷链报警通知发送成功", null);
        } catch (Exception e) {
            log.error("发送冷链报警通知失败", e);
            return Result.error("发送通知失败：" + e.getMessage());
        }
    }

    @Operation(summary = "发送系统通知")
    @PostMapping("/system-notification")
    public Result<Void> sendSystemNotification(@RequestBody SystemNotificationRequest request) {
        log.info("发送系统通知: type={}", request.getType());
        
        try {
            webSocketService.sendSystemNotification(request.getType(), request.getMessage(), request.getData());
            return Result.success("系统通知发送成功", null);
        } catch (Exception e) {
            log.error("发送系统通知失败", e);
            return Result.error("发送通知失败：" + e.getMessage());
        }
    }

    @Operation(summary = "发送产品库存预警")
    @PostMapping("/stock-alert")
    public Result<Void> sendStockAlert(@RequestBody StockAlertRequest request) {
        log.info("发送产品库存预警: productId={}", request.getProductId());
        
        try {
            webSocketService.sendStockAlert(request.getProductId(), request.getProductName(), 
                    request.getCurrentStock(), request.getThreshold());
            return Result.success("库存预警发送成功", null);
        } catch (Exception e) {
            log.error("发送库存预警失败", e);
            return Result.error("发送预警失败：" + e.getMessage());
        }
    }

    @Operation(summary = "获取WebSocket连接统计")
    @GetMapping("/statistics")
    public Result<WebSocketStatistics> getConnectionStatistics() {
        log.info("获取WebSocket连接统计");
        
        try {
            WebSocketStatistics statistics = webSocketService.getConnectionStatistics();
            return Result.success("获取统计信息成功", statistics);
        } catch (Exception e) {
            log.error("获取WebSocket连接统计失败", e);
            return Result.error("获取统计信息失败：" + e.getMessage());
        }
    }

    // 内部请求类
    public static class SendMessageRequest {
        private Long userId;
        private String type;
        private String content;
        private Object data;

        public Long getUserId() { return userId; }
        public void setUserId(Long userId) { this.userId = userId; }
        public String getType() { return type; }
        public void setType(String type) { this.type = type; }
        public String getContent() { return content; }
        public void setContent(String content) { this.content = content; }
        public Object getData() { return data; }
        public void setData(Object data) { this.data = data; }
    }

    public static class BroadcastRequest {
        private String topic;
        private String type;
        private String content;
        private Object data;

        public String getTopic() { return topic; }
        public void setTopic(String topic) { this.topic = topic; }
        public String getType() { return type; }
        public void setType(String type) { this.type = type; }
        public String getContent() { return content; }
        public void setContent(String content) { this.content = content; }
        public Object getData() { return data; }
        public void setData(Object data) { this.data = data; }
    }

    public static class OrderStatusUpdateRequest {
        private Long userId;
        private Long orderId;
        private String status;
        private String message;

        public Long getUserId() { return userId; }
        public void setUserId(Long userId) { this.userId = userId; }
        public Long getOrderId() { return orderId; }
        public void setOrderId(Long orderId) { this.orderId = orderId; }
        public String getStatus() { return status; }
        public void setStatus(String status) { this.status = status; }
        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
    }

    public static class ColdChainAlertRequest {
        private Long userId;
        private String alertType;
        private String message;
        private Object alertData;

        public Long getUserId() { return userId; }
        public void setUserId(Long userId) { this.userId = userId; }
        public String getAlertType() { return alertType; }
        public void setAlertType(String alertType) { this.alertType = alertType; }
        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
        public Object getAlertData() { return alertData; }
        public void setAlertData(Object alertData) { this.alertData = alertData; }
    }

    public static class SystemNotificationRequest {
        private String type;
        private String message;
        private Object data;

        public String getType() { return type; }
        public void setType(String type) { this.type = type; }
        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
        public Object getData() { return data; }
        public void setData(Object data) { this.data = data; }
    }

    public static class StockAlertRequest {
        private Long productId;
        private String productName;
        private Integer currentStock;
        private Integer threshold;

        public Long getProductId() { return productId; }
        public void setProductId(Long productId) { this.productId = productId; }
        public String getProductName() { return productName; }
        public void setProductName(String productName) { this.productName = productName; }
        public Integer getCurrentStock() { return currentStock; }
        public void setCurrentStock(Integer currentStock) { this.currentStock = currentStock; }
        public Integer getThreshold() { return threshold; }
        public void setThreshold(Integer threshold) { this.threshold = threshold; }
    }
}